package memberrank

import (
	"context"
	"encoding/json"

	"mall/service/backend/api/internal/svc"
	"mall/service/backend/api/internal/types"
	"mall/service/backend/api/internal/utils"
	"mall/service/backend/common/i18n"
	"mall/service/backend/common/utils/pointy"
	"mall/service/setting/rpc/settingclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetMemberRankByIdLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetMemberRankByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMemberRankByIdLogic {
	return &GetMemberRankByIdLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetMemberRankByIdLogic) GetMemberRankById(req *types.IDReq) (resp *types.MemberRankInfoResp, err error) {
	data, err := l.svcCtx.SettingRpc.BackendGetMemberRankById(l.ctx, &settingclient.MemberRankIdReq{
		Id:               req.Id,
		WithRestrictions: pointy.GetPointer(uint32(1)),
		WithRules:        pointy.GetPointer(uint32(1)),
	})
	if err != nil {
		return nil, err
	}

	var restrictions []*types.MemberRankRestrictionInfo
	if len(data.Restrictions) > 0 {
		for _, v := range data.Restrictions {
			restrictions = append(restrictions, &types.MemberRankRestrictionInfo{
				BaseIDInfo: types.BaseIDInfo{
					Id: v.Id,
				},
				RankId:    v.RankId,
				TaskId:    v.TaskId,
				Threshold: v.Threshold,
				Sort:      v.Sort,
				Status:    v.Status,
			})
		}
	}
	var rules []*types.MemberRankRuleInfo
	if len(data.Rules) > 0 {
		for _, v := range data.Rules {
			var regions []*types.TreeNode
			if v.Regions != nil {
				if err := json.Unmarshal([]byte(*v.Regions), &regions); err != nil {
					logx.Errorw("GetMemberRankById Rules.Regions json.Unmarshal err", logx.Field("detail", err.Error()))
				}
			}

			rules = append(rules, &types.MemberRankRuleInfo{
				BaseIDInfo: types.BaseIDInfo{
					Id: v.Id,
				},
				RankId:     v.RankId,
				RuleType:   v.RuleType,
				Regions:    regions,
				Mode:       v.Mode,
				Value:      v.Value,
				PeriodType: v.PeriodType,
				Quota:      v.Quota,
				Sort:       v.Sort,
				Status:     v.Status,
			})
		}
	}

	option := utils.GetOptionByStatus(data.Status)

	return &types.MemberRankInfoResp{
		BaseDataInfo: types.BaseDataInfo{
			Success: true,
			Msg:     l.svcCtx.Trans.Trans(l.ctx, i18n.Success),
		},
		Data: &types.MemberRankInfo{
			BaseIDInfo: types.BaseIDInfo{
				Id:         data.Id,
				CreatedAt:  data.CreatedAt,
				UpdatedAt:  data.UpdatedAt,
				DeletedAt:  data.DeletedAt,
				CanAccept:  option.CanAccept,
				CanReject:  option.CanReject,
				CanRemove:  option.CanRemove,
				CanRestore: option.CanRestore,
			},
			Name:           data.Name,
			Code:           data.Code,
			Description:    data.Description,
			Remark:         data.Remark,
			PicId:          data.PicId,
			PicUrl:         data.PicUrl,
			PointThreshold: data.PointThreshold,
			IsDefault:      data.IsDefault,
			Sort:           data.Sort,
			Status:         data.Status,
			Restrictions:   restrictions,
			Rules:          rules,
		},
	}, nil
}
